package org.person.gift.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import org.person.gift.clients.AuthClient;
import org.person.gift.constans.BaseConstants;
import org.person.gift.domain.LoginUser;
import org.person.gift.domain.User;
import org.person.gift.domain.UserInfo;
import org.person.gift.dto.RegisterInfoDto;
import org.person.gift.exception.BusinessException;
import org.person.gift.exception.ResponseCode;
import org.person.gift.exception.SystemAssert;
import org.person.gift.mapper.UserMapper;
import org.person.gift.service.IUserInfoService;
import org.person.gift.service.IUserService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.person.gift.util.AjaxResult;
import org.person.gift.util.StrUtils;
import org.person.gift.util.encrypt.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author MaxPeng
 * @since 2024-01-23
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private AuthClient authClient;

    @Override
    public void smsCodeSend(String phone){
        //1.对电话号码进行非空校验
        SystemAssert.isNotBlank(phone,ResponseCode.RESPONSE_CODE_40024);
        //2.通过电话号码查询用户信息
        Wrapper<User> wrapper = new EntityWrapper<User>().eq("phone", phone);
        int count = selectCount(wrapper);
        //2.1 用户存在就返回错误信息
        if(count > 0 ){
            throw  new BusinessException(ResponseCode.RESPONSE_CODE_40018.getMessage());
        }
        //2.2用户不存在进行下一步
        //3.通过电话号码查询redis中数据判定是否存在
        String smsCodeKey = BaseConstants.SEND_REGISTER_SMS_PREFIX + phone;
        sendSmsCode(smsCodeKey);

        //重新发送验证码短信
    }

    @Override
    @Transactional
    public void register(RegisterInfoDto dto) {
        //1.使用JSR303对传入数据做非空校验
        //2.通过手机号码查询redis中的数据
        String smsCodeKey = BaseConstants.SEND_REGISTER_SMS_PREFIX + dto.getPhone();
        String smsCodeValue = (String)redisTemplate.opsForValue().get(smsCodeKey);
        //2.1 如果为空返回错误信息
        SystemAssert.isNotBlank(smsCodeValue,ResponseCode.RESPONSE_CODE_40020);
        //2.2 如果不为空校验验证码与传入是否匹配
        String[] split = smsCodeValue.split(":");
        String smsCode = split[0];
        //3.1 匹配失败返回错误信息
        SystemAssert.isEq(dto.getSmsCode(),smsCode,ResponseCode.RESPONSE_CODE_40017);
        //3.2 匹配成功存入信息
        //设置密码和盐值
        String salt = UUID.randomUUID().toString();
        String password = MD5.getMD5("gift"+salt+dto.getPassword()+"123");
        //4 存入登录信息表
        LoginUser loginUser = new LoginUser();
        loginUser.setEmail(dto.getEmail());
        loginUser.setUsername(dto.getUsername());
        loginUser.setTel(dto.getPhone());
        loginUser.setType(1);
        loginUser.setPassword(password);
        authClient.save(loginUser);
        if(!AjaxResult.me().isSuccess()){
            throw new BusinessException("注册失败");
        }
        //5 存入用户表
        User user = new User();
        user.setCreateTime(new Date().getTime());
        user.setEmail(dto.getEmail());
        user.setNickName(dto.getUsername());
        user.setPhone(dto.getPhone());
        user.setSalt(salt);
        user.setPassword(password);
        user.setBitState(1L);
        Long loginId = (Long)AjaxResult.me().getResultObj();
        user.setLoginId(loginId);
        insert(user);
        //6 存入用户信息表
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(user.getId());
        userInfo.setCreateTime(new Date().getTime());
        userInfoService.insert(userInfo);
    }



    /**
     * 发送验证码
     * @param smsCodeKey
     */
    public void sendSmsCode(String smsCodeKey) {
        String smsCodeValue = (String)redisTemplate.opsForValue().get(smsCodeKey);
        String smsCode = null;
        if(StrUtil.isNotBlank(smsCodeValue)){
            smsCode = smsCodeValue.split(":")[0];
            String sendTime = smsCodeValue.split(":")[1];

            // 3.1 如果没有过重发时间,返回错误信息
            // 当前时间 - 发送时间   < 1分钟,就是没有过重发时间
            if(System.currentTimeMillis() - Long.parseLong(sendTime) < 60*1000){
                throw new BusinessException(ResponseCode.RESPONSE_CODE_40026);
            }
        }else{
            // 4 如果验证码不存在,生成验证码,放入redis,并短信发送
            // 4.1 生成6位数的随机数作为短信验证码
            smsCode = StrUtils.getRandomString(6);
        }
        // 5 放入redis,并设置5分钟的过期时间和发送时间
        String value = smsCode+":"+ System.currentTimeMillis();
        redisTemplate.opsForValue().set(smsCodeKey,value,5, TimeUnit.MINUTES);
        System.out.println("您的验证码是"+smsCode);
    }
}
